﻿// ....................................................................................................................
//	Author: Copyright (C) 2012 Ing. Marek Hubal
//	Email: hubal@acasoftware.org
// ....................................................................................................................

using System;

namespace core
{
    /// <summary>Trieda INodeList_TGZ</summary>
    public class INodeList_TGZ : INodeList_TAR
    {
        protected byte[] FExpand_SkipBuffer; // Buffer pre citanie obsahu na preskocenie

        /// <summary>Preskocenie bytov pri expandovani</summary>
        /// <param name="pCount">pocet</param>
        protected override void Expand_SkipBytes(long pCount)
        {
            long ToRead = pCount;
            while (ToRead > 0)
            {
                int C = ToRead > FExpand_SkipBuffer.Length ? FExpand_SkipBuffer.Length : (int)ToRead;
                C = FExpand_ArchiveFile.Read(FExpand_SkipBuffer, 0, C);
                if (C == 0) throw (new System.IO.EndOfStreamException());
                ToRead -= C;
            }
            FExpand_CurrentFilePosition += pCount;
        }
        /// <summary>Preskocenie bytov v streame</summary>
        /// <param name="pStream">stream</param>
        /// <param name="pCount">pocet</param>
        protected override void SkipBytesInStream(System.IO.BinaryReader pStream, long pCount)
        {
            if (FExpand_SkipBuffer == null) FExpand_SkipBuffer = new byte[65536];
            long ToRead = pCount;
            while (ToRead > 0)
            {
                int C = ToRead > FExpand_SkipBuffer.Length ? FExpand_SkipBuffer.Length : (int)ToRead;
                C = pStream.Read(FExpand_SkipBuffer, 0, C);
                if (C == 0) throw (new System.IO.EndOfStreamException());
                ToRead -= C;
            }
        }
        /// <summary>Otvorenie streamu pre testovanie</summary>
        /// <param name="pFileName">nazov suboru</param>
        /// <returns>stream</returns>
        protected override System.IO.BinaryReader TestArchive_OpenStream(string pFileName)
        {
            return new System.IO.BinaryReader(new System.IO.Compression.GZipStream(System.IO.File.OpenRead(pFileName), System.IO.Compression.CompressionMode.Decompress));
        }

        /// <summary>Konstruktor</summary>
        /// <param name="pArchiveFileName">nazov suboru archivu</param>
        /// <param name="pRelativePath">relativna cesta v archive</param>
        public INodeList_TGZ(string pArchiveFileName = "", string pRelativePath = "") : base(pArchiveFileName, pRelativePath)
        {
            ArchiveTypeString = "TGZ";
        }

        /// <summary>Zaciatok expandovania obsahu</summary>
        /// <param name="pFilter">objekt filtra</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int BeginExpand(INodeFilters pFilter = null)
        {
            FState = 1; // Nastavim stav expandovania
            try
            {
                FExpand_ArchiveFile = new System.IO.BinaryReader(new System.IO.Compression.GZipStream(System.IO.File.OpenRead(FBaseArchiveFileName), System.IO.Compression.CompressionMode.Decompress)); // Otvorim stream archivu
                FExpand_Buffer = new byte[512]; FExpand_CurrentPosition = 0;
                FExpand_Dirs = new System.Collections.Generic.List<INode>(); FExpand_Files = new System.Collections.Generic.List<INode>();
                FExpand_CurrentFilePosition = 0; FExpand_TotalCount = 0;
                FExpand_SkipBuffer = new byte[65536];
            }
            catch
            {
                return -1; // Nie je mozne otvorit archiv
            }

            FExpand_Expanded = false;
            return 0;
        }
        /// <summary>Otvorenie cache pre citanie</summary>
        /// <returns>true / false</returns>
        public override bool BeginReadCache()
        {
            return BeginReadCache(CacheID);
        }
        /// <summary>Vytvorenie klonu zoznamu</summary>
        /// <returns>objekt zoznamu</returns>
        public override INodeList CloneList()
        {
            return new INodeList_TGZ(FBaseArchiveFileName, FRelativePath);
        }
    }
}
